#include "CommProtocol.h"
#include "Timer.h"
#include "Uart.h"
#include "string.h"
#include "CRC.h"


static uint8_t sReceiveBuffer[UART_BUFFER_SIZE] = {0};     //串口接收缓冲区
static uint16_t sReceiveBufferIndex = 0;                     //串口缓冲区索引
static uint8_t sFrameBuffer[PROTOCOL_MAX_SIZE] = {0};       //数据帧缓冲区   
static ProtocolParseState  sState = enumParseState_WaitHead;


void MoveData(uint8_t *pData, uint16_t nTotalLength, uint16_t nStartPos)
{
    if (NULL == pData)
    {
        return;
    }

    for (int i = nStartPos, j = 0; i < nTotalLength; i++, j++)
    {
        pData[j] = pData[i];      //移动数据
    }
}

void FrameParse()
{


}

void UnPackData()
{
    int nReadCount = 0;
    while ((nReadCount = Uart_Read(&sReceiveBuffer[sReceiveBufferIndex], UART_BUFFER_SIZE - sReceiveBufferIndex)))
    {
        sReceiveBufferIndex += nReadCount;

        if (sReceiveBufferIndex > UART_BUFFER_SIZE)
        {
            sReceiveBufferIndex = 0;
        }

        if (sReceiveBufferIndex < MIN_FRAME_LENGTH)//串口缓冲区数据不足，继续读取
        {
            continue;
        }

        for (int index = 0; index < sReceiveBufferIndex;)
        {
            switch (sState)
            {
                case enumParseState_WaitHead:
                {
                    if (*((uint16_t*)(&sReceiveBuffer[index])) == PROTOCOL_HEAD)            //找到帧头
                    {
                        memcpy(&sFrameBuffer[PROTOCOL_HEAD_POS], &sReceiveBuffer[index], 2);                 //拷贝帧头到帧缓冲区
                        index += 2;                                                     //索引加2
                        sState = enumParseState_WaitVer;                                //等待版本数据
                    }
                    else
                    {
                        MoveData(sReceiveBuffer, sReceiveBufferIndex, 1);
                        sReceiveBufferIndex -= 1;
                        index = 0;
                    }
                }
                break;
                case enumParseState_WaitVer:
                {
                    if (0x01 == sReceiveBuffer[index])
                    {
                        memcpy(&sFrameBuffer[PROTOCOL_FRAME_VER_POS], &sReceiveBuffer[index++], 1);
                        sState = enumParseState_WaitTotalLen;
                    }
                    else
                    {
                        MoveData(sReceiveBuffer, sReceiveBufferIndex, 1);
                        sReceiveBufferIndex -= 1;
                        index = 0;
                        sState = enumParseState_WaitHead;
                    }
                }
                break;
                case enumParseState_WaitTotalLen:
                {
                    if(sReceiveBuffer[index] >= MIN_FRAME_LENGTH)
                    {
                        memcpy(&sFrameBuffer[PROTOCOL_FRAME_LENGEH1_POS], &sReceiveBuffer[index++], 1);
                        sState = enumParseState_WaitCrc1;
                    }
                    else//数据帧长度为0，说明数据有错误
                    {
                        MoveData(sReceiveBuffer, sReceiveBufferIndex, 1);
                        sReceiveBufferIndex -= 1;
                        index = 0;
                        sState = enumParseState_WaitHead;       
                    }
                }
                    break;
                case enumParseState_WaitCrc1:
                {
                    uint16_t nCrc1 = 0;         //传输数据中的CRC1
                    memcpy(&nCrc1, &sReceiveBuffer[index], 2);
                    uint16_t nCalcCrc = CRC16_CCITT(sFrameBuffer, 4);
                    if(nCalcCrc == nCrc1)       //CRC校验成功
                    {
                        memcpy(&sFrameBuffer[PROTOCOL_FRAME_CRC1_POS], &sReceiveBuffer[index], 2);
                        index += 2;
                        sState = enumParseState_WaitCmd;
                    }
                    else
                    {
                        MoveData(sReceiveBuffer, sReceiveBufferIndex, 1);
                        sReceiveBufferIndex -= 1;
                        index = 0;
                        sState = enumParseState_WaitHead;
                    }
                }
                break;
                case enumParseState_WaitCmd:
                {
                    if ((sFrameBuffer[index] > 0) && (sFrameBuffer[index] <= 127))
                    {
                        memcpy(&sFrameBuffer[PROTOCOL_FREAME_CMD_POS], &sReceiveBuffer[index++], 1);
                        sState = enumParseState_WaitData;
                    }
                    else
                    {
                        MoveData(sReceiveBuffer, sReceiveBufferIndex, 1);
                        sReceiveBufferIndex -= 1;
                        index = 0;
                        sState = enumParseState_WaitHead;
                    }
                }
                break;
                case enumParseState_WaitData:
                {
                    int nDataLen = sFrameBuffer[PROTOCOL_FRAME_LENGEH1_POS] - MIN_FRAME_LENGTH;
                    if (0 == nDataLen)
                    {
                        //没有数据部分内容，直接拷贝两字节的CRC校验和
                        memcpy(&sFrameBuffer[PROTOCOL_FRAME_DATA_POS], &sReceiveBuffer[index], 2);
                        sState = enumParseState_Complete;
                    }
                    else if (sReceiveBufferIndex - index >= nDataLen)
                    {
                        //有数据部分内容，拷贝数据部分内容，拷贝CRC校验
                        memcpy(&sFrameBuffer[PROTOCOL_FRAME_DATA_POS], &sReceiveBuffer[index], nDataLen + 2);
                        sState = enumParseState_Complete;

                    }
                    else
                    {
                        //缓冲区剩余数据不够
                        MoveData(sReceiveBuffer, sReceiveBufferIndex, index);
                        sReceiveBufferIndex -= index;
                    }
                }
                break;
                default:
                    break;
            }

            if (enumParseState_Complete == sState)  //解析到一帧数据
            {
                FrameParse();
				int nTemp = sFrameBuffer[PROTOCOL_FRAME_LENGEH1_POS] - MIN_FRAME_LENGTH + 2;
                index += nTemp;
                MoveData(sReceiveBuffer, sReceiveBufferIndex, index);
                sReceiveBufferIndex -= nTemp;
                index = 0;
                sState = enumParseState_WaitHead;
            }
            
        } 
    }
}

void CommProtocol_Init(void)
{
    bool bSuccess = Create_Timer(UnPackData, 10);
}


void SendMessage(uint8_t nCmd, uint8_t *pContent, uint8_t nContentLen)
{
	uint8_t buff[256] = {0};
    //填充协议头，协议版本号
    buff[0] = 0xA5;
	buff[1] = 0xA5;
    buff[2] = 0x01;
    //填充帧长度（整个数据帧 = 固定长度 + 数据长度）
    uint8_t nTotalLen = nContentLen + MIN_FRAME_LENGTH;
    buff[3] = nTotalLen;
	//填充前半部分数据的CRC校验码
	uint16_t nTemp = CRC16_CCITT(buff, 4);
	memcpy(&buff[4], &nTemp, 2);
	//填充指令
    buff[6] = nCmd;
	//填充数据
    if (nContentLen > 0)        //有数据内容就拷贝数据内容
    {
        memcpy(&buff[7], pContent, nContentLen);
    }
    else //没有数据内容就什么都不做
    {

    }
	//填充整个数据的CRC校验
    nTemp = CRC16_CCITT(buff, nTotalLen - 2);
    memcpy(&buff[nTotalLen - 2], &nTemp, 2);
	//通过串口发送数据
    Uart_Send(buff, nTotalLen);
}











